home *** CD-ROM | disk | FTP | other *** search
/ Aminet 40 / Aminet 40 (2000)(Schatztruhe)[!][Dec 2000].iso / Aminet / util / boot / BlizKick.lha / BlizKick / applypatch.e < prev    next >
Text File  |  2000-09-04  |  12KB  |  522 lines

  1. -> FILE: ESrc:Own/applypatch.e          REV: 6 --- apply BlizKick patch module to rom
  2. /* History
  3.    0      started 11th Dec 1999.
  4.    1      works.
  5.    2      12th Dec: added SPEEDROM
  6.    3      added HOGWAITBLIT
  7.    4      added test for <>$f80000 rom
  8.    5      no longer requires MODULES arg, now tests if any patches
  9.           was applied.
  10.    6      27th Mar 2000: added elfloadseg-patch ioerr bug workaround.
  11. */
  12.  
  13. /*
  14.   DESCRIPTION
  15.  
  16.     applypatch can be used to apply BlizKick "patch" kind of modules
  17.     to rom image. Useful if BlizKick doesn't support your system for
  18.     some reason, but you have a working maprom tool for it. applypatch
  19.     can also be used to speed up BlizKick booting by pre-patching rom
  20.     image. BlizKick commandline also gets quite a bit cleaner then. ;)
  21.  
  22.  
  23.   FEATURES
  24.  
  25.   - support for all patch modules that don't try to add resident tags
  26.   - includes HOGWAITBLIT patch of BlizKick
  27.   - includes SPEEDROM patch of BlizKick (kicktag reconnect)
  28.  
  29.  
  30.   RESTRICTIONS
  31.  
  32.   - works only with 512k ROM, 256K is obsolete really
  33.   - requires about 520k memory for patching
  34.   - for obvious reasons there is no undo :)
  35.  
  36.  
  37.   NOTES
  38.  
  39.   - It's a fairly good idea to keep the original ROM images somewhere
  40.     safe
  41.  
  42.  
  43.   SAMPLE RUN
  44.  
  45.     > applypatch DEVS:rom40068.A1200 TO T:rom40068.A1200.patched HOGWAITBLIT \
  46.       SPEEDROM NoClick FixMath404 SpeedyIDE PatchMath020 romfixes
  47.     reading kickfile "DEVS:rom40068.A1200"...
  48.     rom image ok, applying patches...
  49.     applying hogwaitblit patch...
  50.     applying NoClick patch...
  51.     applying FixMath404 patch...
  52.     applying SpeedyIDE patch...
  53.     applying PatchMath020 patch...
  54.     Patched DiceC Mulu routine at offset $27748
  55.     applying romfixes patch...
  56.     applying speedrom patch...
  57.  
  58.     ---- total 7 patches applied ----
  59.     calculating new checksum for image... $2336D49D
  60.     writing patched rom image to "T:rom40068.A1200.patched"...
  61.     done.
  62.  
  63.  
  64.   TODO
  65.  
  66.   - add support for non-EXTRESBUF InstallModule()
  67.   - add support for non-EXTRESBUF modules
  68.  
  69.  
  70.   AUTHOR & LEGAL CRAP
  71.  
  72.     applypatch is written by Harry "Piru" Sintonen 1999-2000.
  73.     applypatch is public domain.
  74.  
  75. */
  76.  
  77.  
  78. OPT OSVERSION=33
  79.  
  80. MODULE 'exec/memory','dos/dos','dos/var'
  81. MODULE 'hardware/dmabits'
  82.  
  83. ENUM ARG_KICKFILE,ARG_TO,ARG_MODULE,ARG_FORCE,ARG_SPEEDROM,
  84.      ARG_HOGWAITBLIT,NUMARGS
  85.  
  86. DEF progname[64]:STRING,array[NUMARGS]:ARRAY OF LONG,
  87.     size=524288
  88.  
  89. PROC main()
  90.  
  91.   IF KickVersion(37)=0
  92.     WriteF('get real! this program requires kickstart 2.04+\n')
  93.     RETURN RETURN_FAIL
  94.   ENDIF
  95.  
  96.   GetProgramName(progname,63); SetStr(progname,StrLen(progname))
  97.  
  98. ENDPROC main2()
  99.  
  100. PROC main2()
  101.   DEF rdargs,r
  102.  
  103.   r:='$VER: applypatch 1.0.2 (27.3.00)'
  104.   FOR r:=0 TO NUMARGS-1; array[r]:=0; ENDFOR
  105.   IF (rdargs:=ReadArgs('FROM=KICKFILE/A,TO/K/A,MODULE/M,FORCE/S,' +
  106.                        'SPEEDROM/S,HOGWAITBLIT/S',array,NIL))
  107.  
  108.     r:=main3(array[ARG_KICKFILE],array[ARG_MODULE])
  109.  
  110.     FreeArgs(rdargs)
  111.   ELSE
  112.     PrintFault(IoErr(),progname)
  113.     r:=RETURN_ERROR
  114.   ENDIF
  115. ENDPROC r
  116.  
  117. ENUM ROMSUMOFFS=$7FFE8,ROMSIZEOFFS=$7FFEC,ROMIDOFFS=$7FFF0,
  118.      BLIZKICK_ID="BlzK"
  119.  
  120. PROC main3(kickfile,modules:PTR TO LONG)
  121.   DEF r,rom:PTR TO LONG,fh,sum,suc=0,err=0
  122.   DEF modpath[256]:STRING,lock=NIL,olddir
  123.  
  124.   PrintF('reading kickfile "\s"...\n',kickfile)
  125.  
  126.   IF FileLength(kickfile)<>size
  127.     PrintF('kickfile "\s" length not \d\n',kickfile,size)
  128.     RETURN RETURN_ERROR
  129.   ENDIF
  130.  
  131.   IF (fh:=Open(kickfile,MODE_OLDFILE))=NIL
  132.     PrintFault(IoErr(),progname)
  133.     PrintF('could not open kickfile "\s"\n',kickfile)
  134.     RETURN RETURN_ERROR
  135.   ENDIF
  136.  
  137.   IF (rom:=New(size))=0
  138.     PrintFault(IoErr(),progname)
  139.     Close(fh)
  140.     PrintF('could not allocate \d bytes of memory\n',size)
  141.     RETURN RETURN_ERROR
  142.   ENDIF
  143.  
  144.   r:=Read(fh,rom,size); Close(fh); fh:=0
  145.   IF r<>size
  146.     PrintFault(IoErr(),progname)
  147.     PrintF('error reading kickfile "\s"\n',kickfile)
  148.     RETURN RETURN_ERROR
  149.   ENDIF
  150.  
  151.   IF (Long(rom+ROMSIZEOFFS)<>size) OR
  152.     ((rom[] AND $FFF8FFFF)<>$11104EF9)
  153.     PrintF('bad rom image!\n')
  154.     RETURN RETURN_ERROR
  155.   ENDIF
  156.  
  157.   r:=Long(rom+4) AND $FFFF0000
  158.   IF r<>$F80000
  159.     PrintF('rom image not located at $00F80000, but $\h[08]!\n',r)
  160.     RETURN RETURN_ERROR
  161.   ENDIF
  162.  
  163.   IF (sum:=romresum(rom,size))<>Long(rom+ROMSUMOFFS)
  164.     IF array[ARG_FORCE]
  165.       PrintF('bad rom checksum $\h[08] should be $\h[08], overrided ' +
  166.              'by FORCE/n',
  167.              sum,Long(rom+ROMSUMOFFS))
  168.     ELSE
  169.       PrintF('bad rom checksum $\h[08] should be $\h[08], can be\n' +
  170.              'overrided with FORCE switch\n',
  171.              sum,Long(rom+ROMSUMOFFS))
  172.       RETURN RETURN_ERROR
  173.     ENDIF
  174.   ENDIF
  175.  
  176.   IF Long(rom+ROMIDOFFS)=BLIZKICK_ID
  177.     IF array[ARG_FORCE]
  178.       PrintF('rom image has been used with BlizKick, but FORCE used\n')
  179.     ELSE
  180.       PrintF('rom image has been used with BlizKick before, can be\n' +
  181.              'overrided with FORCE switch\n')
  182.       RETURN RETURN_ERROR
  183.     ENDIF
  184.   ENDIF
  185.  
  186.   PrintF('rom image ok, applying patches...\n')
  187.  
  188.   -> apply hogwaitblit if enabled
  189.   IF array[ARG_HOGWAITBLIT]
  190.     PrintF('\e[1mapplying hogwaitblit patch...\e[22m\n')
  191.     IF puthogwaitblit(rom,size)
  192.       suc++
  193.     ELSE
  194.       err++
  195.       PrintF('could not patch!\n')
  196.     ENDIF
  197.   ENDIF
  198.  
  199.   IF modules
  200.     -> change dir to ENV:BKMODPATH
  201.  
  202.     IF GetVar('BKMODPATH',modpath,256,GVF_GLOBAL_ONLY)
  203.       IF (lock:=Lock(modpath,ACCESS_READ))
  204.         olddir:=CurrentDir(lock)
  205.       ENDIF
  206.     ENDIF
  207.  
  208.     -> process all modules
  209.  
  210.     WHILE modules[]
  211.       PrintF('\e[1mapplying \s patch...\e[22m\n',modules[]); Flush(stdout)
  212.       IF applypatch(modules[],rom,size) THEN suc++ ELSE err++
  213.       modules++
  214.     ENDWHILE
  215.  
  216.     -> back to orig dir
  217.  
  218.     IF lock
  219.       CurrentDir(olddir)
  220.       UnLock(lock); lock:=0
  221.     ENDIF
  222.  
  223.   ENDIF
  224.  
  225.   -> apply speedrom, if enabled
  226.   IF array[ARG_SPEEDROM]
  227.     PrintF('\e[1mapplying speedrom patch...\e[22m\n')
  228.     IF speedrom(rom,size)
  229.       suc++
  230.     ELSE
  231.       err++
  232.       PrintF('could not patch!\n')
  233.     ENDIF
  234.   ENDIF
  235.  
  236.   IF err
  237.     PrintF('\n\d patch\s failed, output file "\s" not written\n',
  238.            err,IF err=1 THEN '' ELSE 'es',array[ARG_TO])
  239.   ELSE
  240.  
  241.     IF suc=0
  242.       PrintF('\n---- total 0 patches applied ----\ndestination file "\s" not written!\n',
  243.              array[ARG_TO])
  244.     ELSE
  245.  
  246.       PrintF('\n---- total \d patch\s applied ----\ncalculating new checksum for image...',
  247.              suc,IF suc=1 THEN '' ELSE 'es')
  248.  
  249.       -> resum rom
  250.  
  251.       PutLong(rom+ROMSUMOFFS,sum:=romresum(rom,size))
  252.  
  253.       PrintF(' $\h[08]\nwriting patched rom image to "\s"...\n',sum,array[ARG_TO])
  254.  
  255.       -> write rom
  256.  
  257.       IF (fh:=Open(array[ARG_TO],MODE_NEWFILE))=NIL
  258.         PrintFault(IoErr(),progname)
  259.         PrintF('could not open file "\s" for writing\n',array[ARG_TO])
  260.         RETURN RETURN_ERROR
  261.       ENDIF
  262.  
  263.       r:=Write(fh,rom,size); Close(fh); fh:=0
  264.       IF r<>size
  265.         PrintFault(IoErr(),progname)
  266.         DeleteFile(array[ARG_TO])
  267.         PrintF('error writing to "\s", destination file deleted\n',array[ARG_TO])
  268.         RETURN RETURN_ERROR
  269.       ENDIF
  270.     ENDIF
  271.  
  272.   ENDIF
  273.  
  274.   PrintF('done.\n')
  275.  
  276. ENDPROC
  277.  
  278. PROC puthogwaitblit(rom,size)
  279.  
  280.   MOVEM.L D1-D7/A0-A6,-(A7)
  281.  
  282.   MOVE.L  rom,A0
  283.   MOVE.L  size,D0
  284.  
  285.   MOVEQ   #0,D7
  286.  
  287.   CMP.W   #39,$C(A0)         -> Requires rom 39+
  288.   BCS.B   phwb_exit
  289.  
  290.   LEA     -4(A0,D0.L),A1
  291.  
  292.   MOVE.L  #$08390006,D0
  293.   phwb_find:
  294.   ADDQ.L  #2,A0
  295.   CMPA.L  A1,A0
  296.   BEQ.B   phwb_exit
  297.   CMP.L   (A0),D0
  298.   BNE.B   phwb_find
  299.   CMP.L   #$00DFF002,4(A0)
  300.   BNE.B   phwb_find
  301.   CMP.L   #$66024E75,8(A0)
  302.   BNE.B   phwb_find
  303.  
  304.   CMP.L   #$08390006,-8(A0)  -> No KS 1.x!
  305.   BEQ.B   phwb_exit
  306.   CMP.L   #$4A3900DF,-6(A0)  -> KS 2.x/3.x:
  307.   BNE.B   phwb_exit
  308.   SUBQ.L  #6,A0
  309.   LEA     phwb_waitblit(PC),A1
  310.   MOVEQ   #21,D0             -> 42/2
  311.   phwb_copy:
  312.   MOVE.W  (A1)+,(A0)+
  313.   SUBQ.L  #1,D0
  314.   BNE.B   phwb_copy
  315.   MOVEQ   #1,D7
  316.  
  317.   phwb_exit:
  318.   MOVE.L  D7,D0
  319.   MOVEM.L (A7)+,D1-D7/A0-A6
  320.   RETURN  D0
  321.  
  322.   -> 3.0  48 bytes
  323.   -> 3.1  48 bytes
  324.   phwb_waitblit:
  325.   BTST    #6,$DFF002         -> 8 DMAB_BLTDONE=14 dmaconr
  326.   BNE.B   phwb_wb_gowait     -> 2
  327.   RTS                        -> 2
  328.   phwb_wb_gowait:
  329.   MOVE.L  A0,-(A7)           -> 2
  330.   LEA     $DFF002,A0         -> 6 dmaconr
  331.   MOVE.W  #$8400,148(A0)     -> 6 DMAF_SETCLR OR DMAF_BLITHOG dmacon-dmaconr
  332.   phwb_wb_wait:
  333.   BTST    #6,(A0)            -> 4 DMAB_BLTDONE=14 DMAB_BLTDONE-8
  334.   BNE.B   phwb_wb_wait       -> 2
  335.   MOVE.W  #$0400,148(A0)     -> 6 DMAF_BLITHOG dmacon-dmaconr
  336.   MOVE.L  (A7)+,A0           -> 2
  337.   RTS                        -> 2 =42
  338.  
  339. ENDPROC
  340.  
  341. PROC speedrom(rom,size)
  342.  
  343.   -> Reconnect resident modules:
  344.  
  345.   MOVEM.L D1-D7/A0-A6,-(A7)
  346.  
  347.   MOVE.L  rom,A0
  348.   MOVE.L  size,D0
  349.  
  350.   MOVE.L  #$01000000,D2
  351.   SUB.L   D0,D2
  352.   MOVE.L  A0,A5
  353.   SUB.L   D2,A5      -> a5=difference
  354.  
  355.   MOVEQ   #-28,D1    -> -(RT_SIZE+2),D1
  356.   ADD.L   D0,D1
  357.   SUB.L   A1,A1
  358.   sr_find:
  359.   SUBQ.L  #2,D1
  360.   BLS.B   sr_done
  361.   CMP.W   #$4AFC,(A0)+  -> RTC_MATCHWORD,(A0)+
  362.   BNE.B   sr_find
  363.   MOVEQ   #2,D0
  364.   ADD.L   (A0),D0    -> RT_MATCHTAG-2(A0),D0
  365.   ADD.L   A5,D0
  366.   CMP.L   A0,D0
  367.   BNE.B   sr_find
  368.   SUBQ.L  #2,A0
  369.   MOVE.L  A1,D0
  370.   BEQ.B   sr_is_1st
  371.   MOVE.L  A0,D0
  372.   SUB.L   A5,D0
  373.   MOVE.L  D0,6(A1)   -> RT_ENDSKIP(A1)
  374.   sr_is_1st:
  375.   MOVE.L  A0,A1
  376.   LEA     26(A0),A0  ->RT_SIZE(A0),A0
  377.   BRA.B   sr_find
  378.   sr_done:
  379.   MOVE.L  A1,D0
  380.   BEQ.B   sr_none
  381.   -> make last RT_ENDSKIP point $FFFFFE
  382.   MOVE.L  #$FFFFFE,6(A1)
  383.   sr_none:
  384.   MOVEQ   #1,D7
  385.  
  386.   MOVE.L  D7,D0
  387.   MOVEM.L (A7)+,D1-D7/A0-A6
  388. ENDPROC D0
  389.  
  390. ENUM BKMODULE_ID=$707A4E75,BKEP_ID=$4E71
  391.  
  392. PROC applypatch(patch,rom,size)
  393.   DEF ret=0,seg,module:PTR TO LONG
  394.  
  395.   IF (seg:=Lock(patch,ACCESS_READ))
  396.     UnLock(seg)
  397.  
  398.     IF (seg:=LoadSeg(patch))
  399.  
  400.       module:=Shl(seg,2)+4
  401.  
  402.       IF module[]=BKMODULE_ID
  403.         IF module[1]=BKEP_ID
  404.  
  405.           MOVEM.L D1-D7/A0-A6,-(A7)
  406.           LEA     findresident(PC),A2
  407.           LEA     installmodule(PC),A3
  408.           MOVE.L  dosbase,D6
  409.           MOVE.L  execbase,A6
  410.           MOVE.L  rom,A0
  411.           LEA     $F80000,A1
  412.           MOVE.L  #$80000,D0
  413.           MOVE.L  module,A5
  414.           LEA     printf(PC),A4
  415.           JSR     8(A5)
  416.           MOVEM.L (A7)+,D1-D7/A0-A6
  417.           MOVE.L  D0,ret
  418.  
  419.           IF ret=0
  420.             PrintF('failed, module returned error\n')
  421.           ENDIF
  422.  
  423.         ELSE
  424.           PrintF('failed, only patch modules supported!\n')
  425.         ENDIF
  426.       ELSE
  427.         PrintF('failed, not a blizkick module!\n')
  428.       ENDIF
  429.  
  430.       UnLoadSeg(seg)
  431.     ELSE
  432.       PrintFault(IoErr(),progname)
  433.       PrintF('failed, could not load module!\n')
  434.     ENDIF
  435.   ELSE
  436.     PrintFault(IoErr(),progname)
  437.     PrintF('failed, could not load module!\n')
  438.   ENDIF
  439.   RETURN ret
  440.  
  441.  
  442. ->  IN: a0=ptr to ROM, d0=rom len, a1=ptr to resident name
  443. -> OUT: d0=ptr to resident (buf) or NULL
  444. findresident:
  445.   MOVEM.L D1-D7/A0-A6,-(A7)
  446.   MOVEQ   #1,D6
  447.   MOVE.L  A1,A3
  448.   MOVE.L  #$01000000,D2
  449.   SUB.L   D0,D2      -> d2=rom start (rom)
  450.   MOVE.L  A0,A5
  451.   SUB.L   D2,A5      -> A5=diff
  452.   MOVEQ   #26-2,D1   ->RT_SIZE-2,D1
  453.   SUB.L   D1,D0
  454.   MOVE.W  #$4AFC,D1  ->RTC_MATCHWORD,D1
  455.   fr_find:
  456.   SUBQ.L  #2,D0
  457.   BLS.B   fr_exit_nf
  458.   CMP.W   (A0)+,D1
  459.   BNE.B   fr_find
  460.   MOVEQ   #2,D2
  461.   ADD.L   (A0),D2    ->RT_MATCHTAG-2(A0),D2
  462.   ADD.L   A5,D2
  463.   CMP.L   A0,D2
  464.   BNE.B   fr_find
  465.   MOVE.L  12(A0),A1  ->RT_NAME-2(A0),A1
  466.   ADD.L   A5,A1
  467.   MOVE.L  A3,A2
  468.   fr_compare:
  469.   CMPM.B  (A2)+,(A1)+
  470.   BNE.B   fr_find
  471.   TST.B   -1(A2)
  472.   BNE.B   fr_compare
  473.  
  474.   MOVE.L  A0,D0
  475.   SUBQ.L  #2,D0
  476.  
  477.   fr_exit2:
  478.   MOVEM.L (A7)+,D1-D7/A0-A6
  479.   RTS
  480.  
  481.   fr_exit_nf:
  482.   MOVEQ   #0,D0
  483.   BRA.B   fr_exit2
  484.  
  485.  
  486. ->  IN: a0=ptr to ROM, d0=rom len, a1=ptr to module, d6=dosbase
  487. -> OUT: d0=success
  488. installmodule:
  489.   MOVEQ   #0,D0
  490.   RTS
  491.  
  492. ->  IN: a0=FmtString, a1=Array (may be 0), d6=dosbase
  493. printf:
  494.   EXG     D6,A6
  495.   MOVEM.L D0-D2/A0-A1,-(A7)
  496.   MOVE.L  A0,D1
  497.   MOVE.L  A1,D2
  498.   JSR     -$3BA(A6)   -> _LVOVPrintF
  499.   MOVEM.L (A7)+,D0-D2/A0-A1
  500.   EXG     D6,A6
  501.   RTS
  502.  
  503. ENDPROC
  504.  
  505.  
  506. PROC romresum(rom,size)
  507.   MOVE.L  rom,A0
  508.   MOVE.L  size,D0
  509.   MOVE.L  D0,D1
  510.   LSR.L   #2,D1
  511.   MOVE.L  -$18(A0,D0.L),D0
  512.   NOT.L   D0
  513.   rr_loop:
  514.   ADD.L   (A0)+,D0
  515.   BCC.B   rr_skip
  516.   ADDQ.L  #1,D0
  517.   rr_skip:
  518.   SUBQ.L  #1,D1
  519.   BNE.B   rr_loop
  520.   NOT.L   D0
  521. ENDPROC D0
  522.